/*
 * OcurrenciaDeTerminos.cpp
 *
 *  Created on: 06/11/2013
 *      Author: Miguel
 */

#include "OcurrenciaDeTerminos.h"

OcurrenciaDeTerminos::OcurrenciaDeTerminos(const String& nombre, int block_size):
	archivo(block_size)
{
	this->nombre = nombre;
	path = OT_EXT + nombre;
	path_ordenado = "";
}

OcurrenciaDeTerminos::~OcurrenciaDeTerminos() {}

bool OcurrenciaDeTerminos::compararIDs(void* a, void* b) {
	if( ((IDs*)a)->getIdTermino() < ((IDs*)b)->getIdTermino() )
		return true;
	else if ( ((IDs*)a)->getIdTermino() > ((IDs*)b)->getIdTermino() )
		return false;
	else if( ((IDs*)a)->getIdDoc() < ((IDs*)b)->getIdDoc() )
		return true;
	else return false;
}

void OcurrenciaDeTerminos::crear() {
	archivo.create(path);
}

void OcurrenciaDeTerminos::abrir() {
	if( !archivo.open(path) )
		archivo.create(path);
}

void OcurrenciaDeTerminos::cerrar() {
	archivo.close();
}

void OcurrenciaDeTerminos::eliminar() {
	remove( (path+".dat").c_str() );
	remove( (path+".fsm").c_str() );
	remove( (path_ordenado+".dat").c_str() );
	remove( (path_ordenado+".fsm").c_str() );
}

void OcurrenciaDeTerminos::agregarIDAlDoc(BigInt idTerm, BigInt idDoc) {
	IDs nuevo(idTerm, idDoc);
	archivo.add(nuevo);
}

bool OcurrenciaDeTerminos::siguienteID(IDs& sig) {
	if ( !archivo.next(sig) )
		return false;
	return true;
}

String OcurrenciaDeTerminos::ordenar() {
	archivo.open(path);
	SecuentialSort<IDs> ordenador(100, 256, 2);
	ordenador.setMergeName("_ORD"+nombre);
	ordenador.setTempName("_TMP"+nombre);
	path_ordenado = ordenador.sort(archivo, compararIDs);
	archivo.close();
	return path_ordenado;
}

void OcurrenciaDeTerminos::listarOrdenado(){
	archivo.open(path_ordenado);
	archivo.rewind();
	IDs id;
	std::cout << "ARCHIVO ORDENADO: " << path_ordenado << std::endl;
	while( archivo.next(id) )
		id.imprimir();
	archivo.close();
}

/***** IDs *******/
IDs::IDs() {
	idTermino = 0;
	idDoc = 0;
	frecuencia = 0;
}

IDs::IDs(BigInt idTerm, BigInt idDoc) : idTermino(idTerm), idDoc(idDoc) {
	frecuencia = 1;
}

IDs::~IDs(){};

BigInt IDs::getIdTermino() const {
	return idTermino;
}

BigInt IDs::getIdDoc() const {
	return idDoc;
}

BigInt IDs::getFrec() const {
	return frecuencia;
}

void IDs::setFrecuencia(BigInt frec){
	frecuencia = frec;
}

void IDs::imprimir() {
	std::cout << "idTermino: " << idTermino << " idDoc: " << idDoc << " frec: " << frecuencia << std::endl;
}

IDs& IDs::operator=(const IDs& otro) {
	idTermino = otro.idTermino;
	idDoc = otro.idDoc;
	frecuencia = otro.frecuencia;
	return *this;
}

bool IDs::operator ==(const IDs& otro) const{
	return (idTermino == otro.getIdTermino() && idDoc == otro.getIdDoc() );
}

BigInt IDs::size() const {
	return sizeof(idTermino) + sizeof(idDoc) + sizeof(frecuencia);
}

void IDs::serialize(ISerializer& serializer) const {
	serializer.serializeUnsignedLongInt(idTermino);
	serializer.serializeUnsignedLongInt(idDoc);
	serializer.serializeUnsignedLongInt(frecuencia);
}

void IDs::unserialize(IUnserializer& unserializer) {
	idTermino = unserializer.unserializeUnsignedLongInt();
	idDoc = unserializer.unserializeUnsignedLongInt();
	frecuencia = unserializer.unserializeUnsignedLongInt();
}
